package gt.controller.wx;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.CompletionService;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.jsoup.helper.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import gt.common.UrlConstant;
import gt.controller.base.BaseController;
import gt.entity.base.DataMessage;
import gt.entity.bound.Bound;
import gt.entity.city.City;
import gt.entity.payRecord.PayRecord;
import gt.service.bound.BoundService;
import gt.service.city.CityService;
import gt.service.payRecord.PayRecordService;
import gt.util.HttpHelper;
import gt.util.wx.pay.ConfigUtil;
import gt.util.wx.pay.GetClientIp;
import gt.util.wx.pay.PayCommonUtil;
import gt.util.wx.pay.Tyxd;
import gt.util.wx.pay.TyxdUtil;
import gt.util.wx.pay.XMLUtil;

/**
 * 微信支付Controller
 * 
 * @author yst
 * 
 */
@Controller
@RequestMapping("/wxPay")
public class WxPayController extends BaseController {

	@Autowired
	private PayRecordService recordService;

	@Autowired
	private BoundService boundService;

	@Autowired
	private DataMessage dataMessage;
	
	@Autowired
	private CityService cityService;

	// 微信支付线程池
	static Executor wxPay_ex = Executors.newFixedThreadPool(10);
	
	@RequestMapping("/addPayRecord")
	@ResponseBody
	public String addPayRecord(BigDecimal outStandingBalance,
			BigDecimal payMoney, BigDecimal sysIncome, Long agentId,
			Long carrierId, String openId, String settlementCycle,
			String settlementSite,Long carrierSiteId,Long cityId,String cityName) {

		BigDecimal b = new BigDecimal("0");
		// 结果是:-1 小于,0 等于,1 大于
        //校验支付金额是否是0		
		if(payMoney.compareTo(b)!=1){
			this.setDataMessage(dataMessage, 1,null, "请输入大于零的金额哦~"); 
			return JSONObject.fromObject(dataMessage).toString(); 
		}
	    if (outStandingBalance.compareTo(b)!=1 ||
		  sysIncome.compareTo(b)!=1 || agentId ==null || carrierId ==null ||
		  StringUtil.isBlank(openId) || StringUtil.isBlank(settlementCycle)
		  ||StringUtil.isBlank(settlementSite) ) {
			  
			  this.setDataMessage(dataMessage, 1,null, "抱歉，未获得到您的信息，请检查网络稍后再试！"); 
			  return JSONObject.fromObject(dataMessage).toString(); 
		 }
	    
		PayRecord record = new PayRecord();
		record.setPayNo(System.currentTimeMillis() + "");
		record.setPayMoney(payMoney);
		record.setReceiveMoney(sysIncome);
		record.setCarrierId(carrierId);
		record.setCarrierSiteId(carrierSiteId);//子快递公司Id
		record.setAgentId(agentId);
		record.setOpenId(openId);
		record.setCityId(cityId);
		record.setCityName(cityName);
		record.setNotReceiveMoney(outStandingBalance);
		record.setSettlementCycle(settlementCycle);// 结算周期
		record.setSettlementSite(settlementSite);// 结算站点
		record.setPayStatus(0);// 支付状态0待支付，1已确认支付，2支付失败 3取消收款
		record.setIsToldServer(0);// 支付成功后通知server系统(0:未通知1:已通知）
		record.setCreateTime(System.currentTimeMillis());
		record.setUpdateTime(System.currentTimeMillis());
		recordService.add(record);// 添加待支付记录
		this.setDataMessage(dataMessage, 0, record, "插入记录成功");

		return JSONObject.fromObject(dataMessage).toString();
	}

	/**
	 * 微信支付
	 * 
	 * @param openId
	 * @param jinge
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/pay")
	@ResponseBody
	public String pay(HttpServletRequest request, String openId, String orderNo,Long cityId)
			throws Exception {
		
		Tyxd t = new Tyxd();
		String json = "";
		
		SortedMap<Object, Object> params = new TreeMap<Object, Object>();
//		params.put("appId", ConfigUtil.APPID0);//(默认为贯通云网appId)
//		t.setAppid(ConfigUtil.APPID0);// 公众号id(默认为贯通云网公众号Id)
//		t.setMch_id(ConfigUtil.MCH_ID0);// 商户号(默认为贯通云网商户号)
		
		if(cityId!=0&&StringUtils.isNotBlank(orderNo)&&StringUtils.isNotBlank(openId)){
			
			City city =cityService.queryById(cityId);

				if(city.getWxType()==1) {//公众号类型0:贯通云网1:贯通贯云
					t.setAppid(ConfigUtil.APPID1);// 公众号id贯通贯云
					t.setMch_id(ConfigUtil.MCH_ID1);// 商户号贯通贯云
					params.put("appId", ConfigUtil.APPID1);//(默认为贯通贯云appId)
				}else{
					t.setAppid(ConfigUtil.APPID0);// 公众号id贯通云网
					t.setMch_id(ConfigUtil.MCH_ID0);// 商户号 贯通云网
					params.put("appId", ConfigUtil.APPID0);//(默认为贯通云网appId)
				}
		  // BigDecimal realPrice = recordService.queryByPayNo(orderNo).getPayMoney();
		  // t.setTotal_fee(realPrice.multiply(new BigDecimal(100))+"");//真实价格
			t.setNonce_str(PayCommonUtil.CreateNoncestr());// 随机字符串
			t.setBody("代办点结算系统");// 商品描述
			t.setOut_trade_no(orderNo);// 订单号
			t.setTotal_fee("1");// 测试支付价格
			t.setSpbill_create_ip(GetClientIp.getClientIpAddress(request));// 终端ip
			t.setNotify_url(ConfigUtil.SUCCESS_URL);// 支付成功通知地址
			t.setTrade_type("JSAPI");// 交易类型
			t.setOpenid(openId);// 用户标示
			Map<String, String> map = TyxdUtil.sendTyxdMessage(TyxdUtil
					.makeTyxdMessage(t));// 调用微信接口并解析
			System.out.println("+++++++++++++++++++++++++++++++");
			System.out.println("+++++++++++++++++++++++++++++++");
			System.out.println("map：" + map);
			System.out.println("+++++++++++++++++++++++++++++++");
			System.out.println("+++++++++++++++++++++++++++++++");
			// 传值到页面
			//String paySign = PayCommonUtil.ifcreateSign("UTF-8", params,city.getWxType());
			//此处公众号AppId放在上面赋值
			String timestamp = System.currentTimeMillis() + "";
			timestamp = timestamp.substring(0, timestamp.length() - 3);
			params.put("timeStamp", timestamp);
			params.put("nonceStr", PayCommonUtil.CreateNoncestr());
			params.put("package", "prepay_id=" + map.get("prepay_id"));
			params.put("signType", ConfigUtil.SIGN_TYPE);
			String paySign = PayCommonUtil.ifcreateSign("UTF-8", params,city.getWxType());
			params.put("packageValue", "prepay_id=" + map.get("prepay_id")); // 这里用packageValue是预防package是关键字在js获取值出错
			params.put("paySign", paySign); // paySign的生成规则和Sign的生成规则一致
			params.put("sendUrl", "支付成功打开页面地址"); // 付款成功后跳转的页面
			String userAgent = request.getHeader("user-agent");
			char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger") + 15);
			params.put("agent", new String(new char[] { agent }));// 微信版本号，用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
			json = JSONObject.fromObject(params).toString();
		}else{
			json = "参数异常";
		}
			
		return json;
	}

	/**
	 * 接收支付的通知 接收支付成功通知的代码
	 * 
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/paySuccess")
	public void paySuccess(HttpServletRequest request, HttpServletResponse response) throws Exception {
		InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        System.out.println("~~~~~~~~~~~~~~~~付款成功~~~~~~~~~");
        outSteam.close();
        inStream.close();
        String result  = new String(outSteam.toByteArray(),"utf-8");//获取微信调用我们notify_url的返回信息
        Map<Object, Object> map = XMLUtil.doXMLParse(result);
        for(Object keyValue : map.keySet()){
            System.out.println(keyValue+"="+map.get(keyValue));
        }
        if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
        	//订单号
        	String cardNo = map.get("out_trade_no").toString();
        	String wxpayMoney = map.get("total_fee").toString();//微信支付金额
        	String payNumber = map.get("transaction_id").toString();//微信回调后的单号(微信回调时给的)
            //支付成功后执行代码
            response.getWriter().write(PayCommonUtil.setXML("SUCCESS", ""));   //告诉微信服务器，我收到信息了，不要在调用回调action了
            System.out.println("-------------"+PayCommonUtil.setXML("SUCCESS", ""));
     
            //======================================支付成功后后台操作==============================================
    		PayRecord record = recordService.queryByPayNo(cardNo);
    		record.setPayStatus(1);// 支付状态0待支付，1已确认支付，2支付失败 3取消收款
    		record.setWxPayMoney(new BigDecimal(wxpayMoney).divide(new BigDecimal(100)));//"分" 转 "元"
    		record.setUpdateTime(System.currentTimeMillis());
    		this.recordService.edit(record);
    		CompletionService<JSONObject> completionService=new ExecutorCompletionService<JSONObject>(wxPay_ex);
    		//单独起一个线程执行，需判断返回值
    		JSONObject jsonObject = null;
    		System.out.println("-----微信支付成功后的数据处理线程执行成功-----"+jsonObject);
    		
    		for(int i=0;i<3;i++){
    			
    			Future<JSONObject> future=completionService.submit(new wxPayCallable(record,payNumber));
    			jsonObject = future.get();
    			
    			if (("0").equals(jsonObject.getString("result"))) {
        			record.setIsToldServer(1);// 支付成功后通知server系统(0:未通知1:已通知）
        			record.setUpdateTime(System.currentTimeMillis());
            		this.recordService.edit(record);
        			break;
    			}else{
    	        	String errMsg = jsonObject.getString("message").toString();
    	        	  System.out.println("-------return_msg------"+errMsg);
    	        	//失败，休息一分钟
	  				Thread.sleep(60000L);
    	        }
    		}
        }

}
	
	
	
}
